<?php

namespace App\Library\SnowFlake;


use Godruoyi\Snowflake\SequenceResolver;

class SnowFlake
{
    public const TWEPOCH = 1628834159123;

    private static $instance;

    private static function getInstance($datacenterId = 0, $workerId = 0)
    {
        if (!self::$instance) {
            self::$instance = (new \Godruoyi\Snowflake\Snowflake($datacenterId, $workerId))
                ->setStartTimeStamp(self::TWEPOCH);
        }
        return self::$instance;
    }

    /**
     * @param int $datacenterId 数据中心标识位  31 给 收银 POS 了 28 观远
     * @param int $workerId 机器标识位
     * @throws \Exception
     */
    public static function nextId($datacenterId = 0, $workerId = 0)
    {
        return self::getInstance($datacenterId, $workerId)->id();
    }

    public static function nextIdWithShopId($shopId = 0): string
    {
        $workId = $shopId % 32;
        return self::getInstance(0, $workId)->id();
    }

    public static function nextIdWithPid(): string
    {
        $workId = posix_getpid() % 32;
        return self::getInstance(0, $workId)->id();
    }

    /**
     * 通过redis辅助生成id
     */
    public static function nextIdCache()
    {
        return self::getInstance()->setSequenceResolver(new YourSequence)->id();
    }
}

class YourSequence implements SequenceResolver
{
    /**
     *  {@inheritdoc}
     */
    public function sequence(int $currentTime)
    {
        // 范围是0-4095
        return (int)(\Illuminate\Support\Facades\Redis::connection('default')->incr('snowFlakeSequence', 1) % 4096);
    }
}
